﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core.Service;

namespace Cofe.Core.Property
{
    /// <summary>
    /// Contain a list of PropertyRetrivalOptions/IPropertyListSupportedBehavior pairs.
    /// </summary>
    public interface IPropertyBehaviorManager : ICofeService
    {
        IPropertyHost PropertyHost { get; }

        /// <summary>
        /// Get all supported properties and actions, if filters != null, the property must also match any or all of the specified filters.
        /// </summary>
        /// <param name="matchMode"></param>
        /// <param name="options"></param>
        /// <param name="filters"></param>
        /// <returns></returns>
        Task<object[]> GetSupportedPropertyAsync(PropertyRetrivalOptions options = PropertyRetrivalOptions.Default,
            MatchMode matchMode = MatchMode.All, params IPropertyFilter[] filters);

        /// <summary>
        /// Whether support the property specified.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        bool IsPropertySupported(object property);

        /// <summary>
        /// Get value of a property.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        Task<PropertyPair> GetPropertyAsync(object property,
            PropertyRetrivalOptions options = PropertyRetrivalOptions.Default);


        /// <summary>
        /// Get multiple properties.
        /// </summary>
        /// <param name="propertyFilter"></param>
        /// <returns></returns>
        Task<PropertyPair[]> GetPropertyAsync(object[] properties,
            PropertyRetrivalOptions options = PropertyRetrivalOptions.Default);

        /// <summary>
        /// Set value of a property.
        /// </summary>
        /// <exception cref="NotSupportedException">The property do not support write.</exception>
        /// <exception cref="KeyNotFoundException">The property is not supported at all.</exception>
        /// <param name="property"></param>
        /// <param name="value"></param>
        Task<bool> SetPropertyAsync(PropertyPair propertyPair, 
            PropertyRetrivalOptions options = PropertyRetrivalOptions.Default);

        /// <summary>
        /// Invoke an action asynchronously and return the value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="property"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        Task<T> InvokeAsync<T>(object property, ParameterDic parameters = null);

        /// <summary>
        ///  Invoke an action asynchronously.
        /// </summary>
        /// <param name="property"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        Task InvokeAsync(object property, ParameterDic parameters = null);

        /// <summary>
        ///  Invoke an action synchronously and return the value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="property"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        T Invoke<T>(object property, ParameterDic parameters = null);

        /// <summary>
        ///  Invoke an action synchronously.
        /// </summary>
        /// <param name="property"></param>
        /// <param name="parameters"></param>
        void Invoke(object property, ParameterDic parameters = null);

        /// <summary>
        /// If changed properties exists in PropertyCache (via SetProperties), update all changed properties 
        /// to Primary or SecondaryPropertyProvider, and call PropertyCache.ResetChanges.
        /// </summary>
        /// <returns>Number of properties set.</returns>
        Task<int> CommitChangesAsync();

        /// <summary>
        /// remove all changed properties from PropertyCache
        /// </summary>
        /// <returns></returns>
        int ResetChanges();
    }

    public interface IPropertyBehaviorManagerFactory : ICofeService
    {
        IPropertyBehaviorManager ConstructBehavior(IPropertyHost propertyHost, IServiceLocater serviceLocater);
    }


    public interface IPropertyProviderBehavior : ICofeService
    {
        PropertyRetrivalOptions SupportOption { get; }
    }



}
